#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll read(){
    char c=getchar();
    ll x=0,k=1;
    while(c<'0'||c>'9'){
        if(c=='-') k=-1;
        c=getchar();
    }
    while(c>='0'&&c<='9'){
        x=x*10+c-'0';
        c=getchar();
    }
    return x*k;
}
ll T;
ll n,m,l,v,p[100001],ans;
struct car{
    ll d,v,a;
    bool check(ll pos,ll V){
        if(pos<d) return false;
        ll s=pos-d;
        ll v0=v*v+2*a*s;
        return v0>V*V;
    }
}c[100001];
bool f1=true,f2=true;
bool on_off[21];
void dfs(ll dep,ll sum,bitset<21> vis){
    if(dep>m){
        bitset<21>vis1;
        vis1.reset();
        for(int i=1;i<=m;i++){
            if(!on_off[i]) continue;
            for(int j=1;j<=n;j++){
                vis1[j]=vis1[j]|c[j].check(p[i],v);
            }
        }
        if(vis==vis1) ans=max(sum,ans);
        return;
    }
    on_off[dep]=false;
    dfs(dep+1,sum+1,vis);
    on_off[dep]=true;
    dfs(dep+1,sum,vis);
    return;
}
void solve1(){
    bitset<21>vis;
    vis.reset();
    for(int i=1;i<=m;i++){
        for(int j=1;j<=n;j++){
            vis[j]=vis[j]|c[j].check(p[i],v);
        }
    }
    memset(on_off,false,sizeof(on_off));
    ans=0;
    dfs(1ll,0ll,vis);
    printf("%lld %lld\n",ll(vis.count()),ans);
    return;
}
void solve2(){
    bitset<100001>vis;
    vis.reset();
    for(int j=1;j<=n;j++) vis[j]=vis[j]|c[j].check(p[m],v);
    if(vis.count()==0) ans=m;
    else ans=m-1;
    printf("%lld %lld\n",ll(vis.count()),ans);
    return;
}
int main(){
    freopen("detect.in","r",stdin);
    freopen("detect.out","w",stdout);
    T=read();
    while(T--){
        n=read();m=read();l=read();v=read();
        for(int i=1;i<=n;i++){
            c[i].d=read();c[i].v=read();c[i].a=read();
            if(c[i].a<0) f1=false;
            if(c[i].a>=0) f2=false;
        }
        for(int i=1;i<=m;i++) p[i]=read();
        if(n<=20){
            solve1();
        }else if(f1){
            solve2();
        }else{
            ans=0;
            bitset<100001>vis;
            vis.reset();
            for(int i=1;i<=m;i++){
                bool f=false;
                for(int j=1;j<=n;j++){
                    if(vis[j]==false&&c[j].check(p[i],v)==true){
                        f=true;
                        vis[j]=true;
                    }
                }
                if(!f) ans++;
            }
            printf("%lld %lld\n",ll(vis.count()),ans);
        }
    }
    return 0;
}